package app;

import java.util.ArrayList;
import java.util.Iterator;

import color.Color;

import cluster.Cluster;

import organisms.*;
import organisms.*;

import processing.core.PApplet;
import field.AngleField;
import geom.Line;
import geom.PolarVector;
import geom.Segment;
import geom.Vector;


public class ColorFielders extends PApplet{
	ArrayList<ColorTracer> tracers;
	ArrayList<LineMover> liners;
	Cluster<Color> colors;
	AngleField field;
	int width = 1440;
	int height = 900;
	
	static public void main(String args[]) {
		PApplet.main(new String[] { 

			//"--present",
			"app.ColorFielders" 
		});
	}
	
	public void setup(){
		frameRate(50);
		size(width, height);
		smooth();
		tracers = new ArrayList<ColorTracer>();
		liners = new ArrayList<LineMover>();
		field = new AngleField(new Vector(width, height, 0));
		background(90, 100, 80);
		colors = new Cluster<Color>("vangogh-cafe_CLUSTER.xml", this);
	}
	
	public void keyPressed(){
		if(key == 'a'){
			addTracer();
		}
		if(key == 'A'){
			addTracer();
			ColorTracer tracer = tracers.get(tracers.size()-1);
			Vector pos = tracer.getPos();
			Vector speed = tracer.getSpeed();
			//drawField(tracer);
			//tracer.reset(pos, speed);
			//
			
			drawProper();
			
		}
		if(key == 'l'){
			
				addLiner();
			
		}
		if(key == 'c'){
			tracers = new ArrayList<ColorTracer>();
			field = new AngleField(new Vector(width, height, 0));
			liners = new ArrayList<LineMover>();
			background(255);
		}
		if(key == 'b'){
			drawBins = !drawBins;
		}
		if(key == ENTER){
			println("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
		}
		if(key == 't'){
			scope = !scope;
		}
			
	}
	int lined = 0;
	public void addLiner(){
		liners.add(new LineMover(this, field, colors, new Vector(), 
				tracers.get((int)Math.floor(Math.random() * tracers.size())).getTrace()));
	}
	int selectedTracer;
	public void drawField(ColorTracer tr){
		background(255);
		float res = 50; 
		
		for(int x = 0; x < res; x++){
			for(int y = 0; y < res; y++){
				Vector pos = new Vector((float)x * width / res, (float)y * height / res, 0);
				tr.setPos(pos, false);
				Vector f = field.getFieldValue(tr.getInterpreter()).normalize().mult(5f);
				Vector s = pos.add(f);
				Vector e = pos.sub(f);
				
				PApplet.println("start: " + s + " end: " + e);
				stroke(0, 60);
				fill(0, 150);
				ellipse(tr.getPos().x, tr.getPos().y, 2, 2);
				noFill();
				line(s.x, s.y, e.x, e.y);
				
			}
		}
	}
	
	
	
	boolean scope = false;
	public void drawFieldScope(Vector x, float m){
		float size = 300;
		float res = 30;
		float length = size / res;
		
		for(int i = 0; i < res; i++){
			for(int k = 0; k < res; k++){
				Vector pos = new Vector((i+1)*length, (k+1)*length, 0);
				Vector sample = x.sub(new Vector(size/2f, size/2f, 0)).add(pos.mult(1f/m));
				if(i == 0 || i == res - 1 || k == 0 || k == res -1);
				//Vector f = field.value(sample, this);
				ellipse(pos.x, pos.y, 2, 2);
				//Vector epos = pos.add(f.mult(7));
				//line(pos.x, pos.y, epos.x, epos.y);
			}
		}
		
		
		
		
		
	}
	public void mousePressed(){
		drawSegments = true;
		if(mousePath != null){
			mousePaths.add(mousePath);
		}
		mousePath = new Line(this);
	}
	
	public void mouseReleased(){
		drawSegments = false;
	}
	
	public void mouseDragged(){
		Vector pos = new Vector(mouseX, mouseY, 0);
		mousePath.addPoint(pos);
		if(mousePath.length() > 1){
			field.add(new Segment(mousePath, mousePath.size()-2, mousePath.size()-1));
		}
		mousePath.draw();
	}
	boolean drawSegments = false;
	ArrayList<Line> mousePaths = new ArrayList<Line>();
	Line mousePath;

	
	public void addTracer(){
		float dist = (float)Math.sqrt(Math.pow(height/2f, 2) + Math.pow(width/2f, 2));
		PApplet.println("addtracer");
		Vector pos = new PolarVector(random(2 * PI), 0,  dist).getCartesian().add(new Vector(width /2f, height/2f, 0));
		Vector speed = new Vector(random(width), random(height), 0).sub(pos).normalize().mult(8);
		PApplet.println("pos speed " + pos + " ;;; " + speed);
		ColorTracer tracer = new ColorTracer((PApplet)this, colors, field, pos, speed);
		tracers.add(tracer);
		
		PApplet.println("addedd tracer");
	}
	boolean drawBins = false;
	public void drawProper(){
		Iterator<ColorTracer> it = tracers.iterator();
		while(it.hasNext()){
			Tracer next = it.next();
			next.draw();
			
		}
	}
	
	public void draw(){
		//PApplet.println("segments in field: " + field.getAllSegments().size());
		if(drawBins) field.draw(this);
		Iterator<ColorTracer> it = tracers.iterator();
		while(it.hasNext()){
			Tracer next = it.next();
			if(!scope){
				next.move();
			}
			next.drawTrace();
			
		}
		
		Iterator<LineMover> lmit = liners.iterator();
		while(lmit.hasNext()){
			LineMover next = lmit.next();
			if(!scope){
				next.move();
				//PApplet.println(next.getPos());
			}
			next.drawTrace();
			
		}
		if(scope){
			drawFieldScope(new Vector(mouseX, mouseY, 0), 10);
		}
	}
}
